package org.example.service;

import com.google.common.collect.Lists;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.example.dao.NestedSkuRepository;
import org.example.dao.SkuRepository;
import org.example.entity.Attribute;
import org.example.entity.NestedSku;
import org.example.entity.Sku;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.BulkOptions;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class NestedSkuService {

    @Resource
    private NestedSkuRepository nestedSkuRepository;

    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    public void batch() {
        List<NestedSku> list = Lists.newArrayList();
        for (int i = 0; i < 500000; i++) {
            NestedSku sku = new NestedSku();
            sku.setCategoryId(103);
            sku.setPrice(new BigDecimal("99.99"));
            sku.setShelfTime(new Date());

            List<Attribute> attribute = new ArrayList<>();
            attribute.add(new Attribute("1", "按系统",  Lists.newArrayList("安卓QQ"), null, null, null));
            attribute.add(new Attribute("2", "实名情况", Lists.newArrayList("可二次实名"), null, null, null));
            attribute.add(new Attribute("3", "史诗皮肤数量", null, 10d, null, null));
            attribute.add(new Attribute("4", "段位", Lists.newArrayList( "至圣王者"), null, null, null));
            attribute.add(new Attribute("5", "小国标", Lists.newArrayList("国服少司缘", "国服元流之子(法师)"), null, null, null));
            attribute.add(new Attribute("6", "大国标", Lists.newArrayList("大国标艾琳",  "大国标钟馗"), null, null, null));
            attribute.add(new Attribute("7", "传说皮肤", Lists.newArrayList("鲁班七号时之奇旅", "花木兰冠军飞将"), null, null, null));

            sku.setAttribute(attribute);
            list.add(sku);

            sku = new NestedSku();
            sku.setCategoryId(104);
            sku.setPrice(new BigDecimal("99.99"));
            sku.setShelfTime(new Date());

            attribute = new ArrayList<>();
            attribute.add(new Attribute("100", "账号类型",  Lists.newArrayList("微信"), null, null, null));
            attribute.add(new Attribute("101", "实名情况", Lists.newArrayList("不可二次实名"), null, null, null));
            attribute.add(new Attribute("102", "刀皮数量", null, 3d, null, null));
            attribute.add(new Attribute("103", "段位", Lists.newArrayList("源能战魂"), null, null, null));

            sku.setAttribute(attribute);
            list.add(sku);

            sku = new NestedSku();
            sku.setCategoryId(105);
            sku.setPrice(new BigDecimal(i + ""));
            sku.setShelfTime(new Date());

            attribute = new ArrayList<>();
            attribute.add(new Attribute("1001", "账号类型",  Lists.newArrayList("三国杀移动版"), null, null, null));
            attribute.add(new Attribute("1002", "账号分类", Lists.newArrayList("苹果账号"), null, null, null));
            attribute.add(new Attribute("1004", "数量", null, Double.valueOf(i + ""), null, null));
            attribute.add(new Attribute("1003", "渠道分类", Lists.newArrayList("官服微信"), null, null, null));

            sku.setAttribute(attribute);
            list.add(sku);

            if (i%2000==0) {
                // 将对象列表转换为 IndexQuery 列表
                List<IndexQuery> queries = list.stream()
                        .map(item -> {
                            IndexQuery query = new IndexQuery();
                            query.setObject(item);
                            return query;
                        })
                        .collect(Collectors.toList());

                // 执行批量写入--这个接口不会生成mapping为nested结构，需要调用nestedSkuRepository.save(sku);才能生成
                elasticsearchRestTemplate.bulkOperation(queries, BulkOptions.defaultOptions(), IndexCoordinates.of("nested_sku"));

                list.clear();
            }
        }


    }

    public void searchByCategoryId() {
        long l = System.currentTimeMillis();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
                .must(QueryBuilders.termQuery("categoryId", 101));
        boolQueryBuilder.must(QueryBuilders.nestedQuery("attribute", QueryBuilders.boolQuery().must(QueryBuilders.termQuery("attribute.key", "1")).must(QueryBuilders.termQuery("attribute.textValue", "苹果微信")), ScoreMode.None));
        boolQueryBuilder.must(QueryBuilders.nestedQuery("attribute", QueryBuilders.boolQuery().must(QueryBuilders.termQuery("attribute.key", "2")).must(QueryBuilders.termQuery("attribute.textValue", "可二次实名")), ScoreMode.None));
        boolQueryBuilder.must(QueryBuilders.nestedQuery("attribute", QueryBuilders.boolQuery().must(QueryBuilders.termQuery("attribute.key", "6")).must(QueryBuilders.termQuery("attribute.textValue", "大国标上官婉儿")), ScoreMode.None));
        boolQueryBuilder.must(QueryBuilders.nestedQuery("attribute", QueryBuilders.boolQuery().must(QueryBuilders.termQuery("attribute.key", "3")).must(QueryBuilders.rangeQuery("attribute.numberValue").gte(3)), ScoreMode.None));

        NativeSearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                // date, int, bigDecimal都可以直接指明字段排序
//                .withSort(SortBuilders.fieldSort("shelfTime").order(SortOrder.DESC))
                .build();
        List<SearchHit<NestedSku>> searchHits = elasticsearchRestTemplate.search(query, NestedSku.class).getSearchHits();
        System.out.println(searchHits.size());
        System.out.println(System.currentTimeMillis() - l);
    }

    public void inset() {
        NestedSku sku = new NestedSku();
        sku.setCategoryId(101);
        sku.setPrice(new BigDecimal("99.99"));
        sku.setShelfTime(new Date());

        List<Attribute> attribute = new ArrayList<>();
        attribute.add(new Attribute("1", "按系统",  Lists.newArrayList("苹果微信"), null, null, null));
        attribute.add(new Attribute("2", "实名情况", Lists.newArrayList("不可二次实名"), null, null, null));
        attribute.add(new Attribute("3", "史诗皮肤数量", null, 3d, null, null));
        attribute.add(new Attribute("4", "段位", Lists.newArrayList("传奇王者", "荣耀王者", "绝世王者", "非凡王者", "无双王者", "至圣王者"), null, null, null));
        attribute.add(new Attribute("5", "小国标", Lists.newArrayList("国服少司缘", "国服元流之子(法师)", "国服大司命", "国服莱西奥", "国服云缨", "国服金蝉"), null, null, null));
        attribute.add(new Attribute("6", "大国标", Lists.newArrayList("大国标艾琳", "大国标镜", "大国标鲁班大师", "大国标上官婉儿", "大国标女娲", "大国标钟馗"), null, null, null));
        attribute.add(new Attribute("7", "传说皮肤", Lists.newArrayList("鲁班七号时之奇旅", "花木兰冠军飞将", "李元芳飞鸢探春", "女娲补天", "伽罗太华", "露娜霜月吟"), null, null, null));

        sku.setAttribute(attribute);
        nestedSkuRepository.save(sku);

        sku = new NestedSku();
        sku.setCategoryId(102);
        sku.setPrice(new BigDecimal("99.99"));
        sku.setShelfTime(new Date());

        attribute = new ArrayList<>();
        attribute.add(new Attribute("8", "账号类型",  Lists.newArrayList("微信"), null, null, null));
        attribute.add(new Attribute("9", "实名情况", Lists.newArrayList("不可二次实名"), null, null, null));
        attribute.add(new Attribute("11", "刀皮数量", null, 3d, null, null));
        attribute.add(new Attribute("10", "段位", Lists.newArrayList("源能战魂"), null, null, null));

        sku.setAttribute(attribute);
        nestedSkuRepository.save(sku);
    }
}
